﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace ESP.Data
{
    public class InsertCommandParameters : CommandParameters
    {
        private IEnumerable<LambdaExpression> _expressions;

        public InsertCommandParameters(string token, IEnumerable<LambdaExpression> expressions)
            : base(token)
        {
            _expressions = expressions;
        }

        protected internal override void Build()
        {
            if (_expressions == null)
            {
                SubParameters.Add("COL", string.Empty);
                SubParameters.Add("VAL", string.Empty);
                return;
            }

            StringBuilder builderCol = new StringBuilder();
            StringBuilder builderVal = new StringBuilder();

            bool isFirst = true;
            foreach (var exp in _expressions)
            {
                if (!isFirst)
                {
                    builderCol.Append(", ");
                    builderVal.Append(", ");
                }
                else
                {
                    isFirst = false;
                }
                TranslateExpression(builderCol, builderVal, exp.Body);
            }

            SubParameters.Add("COL", builderCol.ToString());
            SubParameters.Add("VAL", builderVal.ToString());
        }

        private void TranslateExpression(StringBuilder builderCol, StringBuilder builderVal, Expression expression)
        {
            var updateCall = (MethodCallExpression)expression;

            if (updateCall.Method.DeclaringType != typeof(UpdateExtensions))
            {
                throw new InvalidCastException();
            }

            var arg0 = updateCall.Arguments[0];
            if (arg0.NodeType == ExpressionType.Convert)
            {
                arg0 = ((System.Linq.Expressions.UnaryExpression)arg0).Operand;
            }

            var member = (MemberExpression)arg0;

            builderCol.Append("[").Append(member.Member.Name).Append("]");
            TranslateExpression(builderVal, updateCall.Arguments[1], new Dictionary<ParameterExpression, string>());
        }
    }
}
